import { createReducer, createActions } from 'reduxsauce'
import Immutable from 'seamless-immutable'

/* ------------- Types and Action Creators ------------- */

const { Types, Creators } = createActions({
  getAllRequest: ['token'],
  getAllSuccess: ['payload'],
  getAllFailure: null,
  createRequest: ['token','data'],
  createSuccess: ['id'],
  createFailure: null,
  updateRequest: ['token','index','data'],
  updateSuccess: null,
  updateFailure: null,
  deleteRequest: ['token','index','id'],
  deleteSuccess: null,
  deleteFailure: null,
  activeSet: ['active']
})

export const AddressTypes = Types
export default Creators

/* ------------- Initial State ------------- */

export const INITIAL_STATE = Immutable({
  index: null, // for update
  data: null, // for cache, but only for one task
  active: 0,
  payload: null,
  fetching: null,
  error: null,
})

/* ------------- Reducers ------------- */

// set active address
export const activeSet = (state, {active}) => state.merge({active:active})

// request the data from an api
export const getAllRequest = (state, {token}) =>
  state.merge({ fetching: true, payload: null, error:null})

// successful api lookup
export const getAllSuccess = (state, action) => {
  const { payload } = action
  return state.merge({ fetching: false, error: null, payload })
}

// Something went wrong somewhere.
export const getAllFailure = state =>
  state.merge({ fetching: false, error: true, payload: null })

// unshift created to payload
export const createRequest = (state,action) => {
  const {data} = action
  return state.merge({fetching:true,error:null,data})
}

// set id for new created
export const createSuccess = (state,action) => {
  let payload = null
  if(state.payload) {
    payload = [{...state.data,id:action.id},...state.payload]
  } else {
    payload = [{...state.data, id:action.id}]
  }
  return state.merge({
    fetching:false,
    error:null,
    data: null,
    payload: payload,
  })
}

// if created failure, remove new created
export const createFailure = (state,action) => {
  return state.merge({fetching:false,error:true,data:null})
}

// // update item, leave data for failure
// wait success to update
export const updateRequest = (state,action) => {
  const {index, data} = action
  //let payload = state.payload
  //payload[index] = data
  return state.merge({fetching:true,error:null,index,data})
}

// if update success
export const updateSuccess = (state,action) => {
  return state.merge({
    fetching:false,
    error:null,
    index:null,
    data:null,
    payload: state.payload.map((item,index)=>{
      if(index !== state.index) {
        return item
      }
      return {
        ...item,
        ...state.data
      }
    })
  })
}

// if update failure
export const updateFailure = (state,action) => {
  return state.merge({fetching:false,error:true,index:null,data:null})
}

export const deleteRequest = (state,action) => {
  const {index} = action
  return state.merge({fetching:true,error:null,index})
}

export const deleteSuccess = (state,action) => {
  // const {index} = state
  // let payload = state.payload
  // payload = payload.splice(indx,1) // remove item by index
  return state.merge({
    fetching:false,
    error:null,
    index:null,
    payload: state.payload.filter((item,index) => index !== state.index),
  })
}

export const deleteFailure = (state,action) => {
  return state.merge({fetching:false,error:true,index:null})
}

/* ------------- Hookup Reducers To Types ------------- */

export const reducer = createReducer(INITIAL_STATE, {
  [Types.GET_ALL_REQUEST]: getAllRequest,
  [Types.GET_ALL_SUCCESS]: getAllSuccess,
  [Types.GET_ALL_FAILURE]: getAllFailure,
  [Types.CREATE_REQUEST]: createRequest,
  [Types.CREATE_SUCCESS]: createSuccess,
  [Types.CREATE_FAILURE]: createFailure,
  [Types.UPDATE_REQUEST]: updateRequest,
  [Types.UPDATE_SUCCESS]: updateSuccess,
  [Types.UPDATE_FAILURE]: updateFailure,
  [Types.DELETE_REQUEST]: deleteRequest,
  [Types.DELETE_SUCCESS]: deleteSuccess,
  [Types.DELETE_FAILURE]: deleteFailure,
  [Types.ACTIVE_SET]: activeSet,
})
